/*
 * @Author: xiaosihan
 * @Date: 2024-08-25 17:38:32
 * @Last Modified by: xiaosihan
 * @Last Modified time: 2024-08-25 20:54:44
 */

import utils from "@utils";
import homeStore from "@views/home/homeStore";
import { autorun } from "mobx";
import {
  AmbientLight,
  BackSide,
  BoxGeometry,
  DirectionalLight,
  Mesh,
  MeshLambertMaterial,
  PerspectiveCamera,
  Vector3,
} from "three";
import ThreeBase from "three-base";
import MeshBase from "three-base/MeshBase";
import threeUtils from "three-base/threeUtils";
import { degToRad } from "three/src/math/MathUtils";

/**
 * @class HomeRender
 * @extends {ThreeBase}
 */
class ModelViewRender extends ThreeBase {
  constructor() {
    super();
  }

  // 环境光
  ambientLight = (() => {
    const ambientLight = new AmbientLight("#fff", 1.5);
    this.scene.add(ambientLight);
    return ambientLight;
  })();

  init() {
    super.init();
    this.axesHelper.visible = false;
    this.gridHelper.visible = false;
    this.controls.enableZoom = utils.isDev;
    this.controls.enablePan = false;
    this.controls.rotateSpeed = 1;
    this.controls.enableRotate = true;
    this.controls.maxPolarAngle = degToRad(90);
    this.controls.minPolarAngle = degToRad(90);
    this.renderer.shadowMap.enabled = true;
    this.renderer.shadowMap.autoUpdate = true;

    // this.addEventListener("beforeRender", () => {
    //   const { position, center } = this.getLookAt();
    //   this.box.position.copy(center);
    //   this.box.lookAt(position);
    //   this.box.updateMatrixWorld(true);
    // });
  }

  //   box = (() => {
  //     const boxGeo = new BoxGeometry(1, 1, 1, 1, 1, 1);
  //     const box = new Mesh(
  //       boxGeo,
  //       new MeshLambertMaterial({ color: "#ffffff", side: BackSide })
  //     );
  //     box.scale.set(0, 0, 0);
  //     box.receiveShadow = true;
  //     this.scene.add(box);
  //     return box;
  //   })();

  // 方向光
  directionalLight = (() => {
    const directionalLight = new DirectionalLight("#fff", 1.5);
    directionalLight.position.set(2, 1, 5);
    directionalLight.target.position.set(0, 0, 0);
    directionalLight.castShadow = true;
    directionalLight.shadow.mapSize.set(4096, 4096);
    directionalLight.shadow.camera.left = -10;
    directionalLight.shadow.camera.top = 10;
    directionalLight.shadow.camera.bottom = -10;
    directionalLight.shadow.camera.right = 10;
    this.add(directionalLight);
    return directionalLight;
  })();

  // 用于预览的模型
  mesh = (() => {
    const mesh = new MeshBase();
    mesh.castShadow = true;
    this.add(mesh);
    return mesh;
  })();

  dispose = autorun(async () => {
    const { role } = homeStore;
    let meshChange = false;
    switch (role) {
      case "1":
        if (this.mesh.url !== "./1.glb") {
          meshChange = true;
          await this.mesh.loadModel("./1.glb");
          this.lookatObjects({
            objects: [this.mesh],
            direction: new Vector3(0, 0, 1),
            distance: 1,
            duration: 1,
            offset: new Vector3(0, -0.1, 0),
          });
        }
        break;
      case "2":
        if (this.mesh.url !== "./aisha.glb") {
          meshChange = true;
          await this.mesh.loadModel("./aisha.glb");
          this.lookatObjects({
            objects: [this.mesh],
            direction: new Vector3(0, 0, 1),
            distance: 1,
            duration: 1,
            offset: new Vector3(0, -0.1, 0),
          });
        }
        break;
      default:
        break;
    }

    if (meshChange) {
      await new Promise((resolve) => setTimeout(resolve, 200));
      const { fov, aspect } = this.getCamera() as PerspectiveCamera;
      const { position, center } = this.getLookAt();
      const diatance = position.distanceTo(center);
      const hanlfWidth = diatance * Math.tan(fov / 2);
      const size = threeUtils.getSize(this.mesh);
    //   this.box.scale.set(size.y * aspect, size.y, hanlfWidth);

      this.directionalLight.shadow.camera.left = -Math.max(
        size.y,
        size.y * aspect
      );
      this.directionalLight.shadow.camera.top = Math.max(
        size.y,
        size.y * aspect
      );
      this.directionalLight.shadow.camera.bottom = -Math.max(
        size.y,
        size.y * aspect
      );
      this.directionalLight.shadow.camera.right = Math.max(
        size.y,
        size.y * aspect
      );
    }

    const animas = this.mesh.getAnimas();
    console.log("animas", animas);
    homeStore.setAnimas(animas);
  });

  dispose1 = autorun(() => {
    const { anima } = homeStore;
    this.mesh.setAnimas(anima);
  });

  async setSize(width: number, height: number): Promise<void> {
    super.setSize(width, height);
    await new Promise((resolve) => setTimeout(resolve, 100));
    const { fov, aspect } = this.getCamera() as PerspectiveCamera;
    const { position, center } = this.getLookAt();
    const diatance = position.distanceTo(center);
    const hanlfWidth = diatance * Math.tan(fov / 2);
    const size = threeUtils.getSize(this.mesh);
    // this.box.scale.set(size.y * aspect, size.y, hanlfWidth);

    this.directionalLight.shadow.camera.left = -Math.max(
      size.y,
      size.y * aspect
    );
    this.directionalLight.shadow.camera.top = Math.max(size.y, size.y * aspect);
    this.directionalLight.shadow.camera.bottom = -Math.max(
      size.y,
      size.y * aspect
    );
    this.directionalLight.shadow.camera.right = Math.max(
      size.y,
      size.y * aspect
    );
  }

  render(): void {
    super.render();
  }
}

const modelViewRender = (window.modelViewRender = new ModelViewRender());

export default modelViewRender;
